package org.jivesoftware.smackx;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketInterceptor;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smackx.packet.CapsExtension;
import org.jivesoftware.smackx.packet.DataForm;
import org.jivesoftware.smackx.packet.DiscoverInfo;
import org.jivesoftware.smackx.packet.DiscoverInfo.Identity;
import org.jivesoftware.smackx.packet.DiscoverItems;
import org.jivesoftware.smackx.packet.DiscoverItems.Item;

public class ServiceDiscoveryManager
{
  private static boolean cacheNonCaps;
  private static String entityNode;
  private static String identityName = "Smack";
  private static String identityType = "pc";
  private static Map<Connection, ServiceDiscoveryManager> instances;
  private EntityCapsManager capsManager;
  private Connection connection;
  private String currentCapsVersion = null;
  private DataForm extendedInfo;
  private final List<String> features;
  private Map<String, NodeInformationProvider> nodeInformationProviders;
  private Map<String, DiscoverInfo> nonCapsCache;
  private boolean sendPresence = false;

  static
  {
    entityNode = "http://www.igniterealtime.org/projects/smack/";
    cacheNonCaps = true;
    instances = new ConcurrentHashMap();
    XMPPConnection.addConnectionCreationListener(new ConnectionCreationListener()
    {
      public void connectionCreated()
      {
        new ServiceDiscoveryManager(paramConnection);
      }
    });
  }

  public ServiceDiscoveryManager(Connection paramConnection)
  {
    this.nonCapsCache = new ConcurrentHashMap();
    this.features = new ArrayList();
    this.extendedInfo = null;
    this.nodeInformationProviders = new ConcurrentHashMap();
    this.connection = paramConnection;
    if (paramConnection instanceof XMPPConnection)
    {
      setEntityCapsManager(new EntityCapsManager());
      this.capsManager.addCapsVerListener(new CapsPresenceRenewer(this, null));
    }
    renewEntityCapsVersion();
    init();
  }

  public static boolean canPublishItems(DiscoverInfo paramDiscoverInfo)
  {
    return paramDiscoverInfo.containsFeature("http://jabber.org/protocol/disco#publish");
  }

  private DiscoverInfo cloneDiscoverInfo(DiscoverInfo paramDiscoverInfo)
  {
    return paramDiscoverInfo.clone();
  }

  private String getEntityCapsVersion()
  {
    String str;
    if (this.capsManager != null)
      str = this.capsManager.getCapsVersion();
    while (true)
    {
      return str;
      str = null;
    }
  }

  public static String getIdentityName()
  {
    return identityName;
  }

  public static String getIdentityType()
  {
    return identityType;
  }

  public static ServiceDiscoveryManager getInstanceFor(Connection paramConnection)
  {
    return ((ServiceDiscoveryManager)instances.get(paramConnection));
  }

  private NodeInformationProvider getNodeInformationProvider(String paramString)
  {
    NodeInformationProvider localNodeInformationProvider;
    if (paramString == null)
      localNodeInformationProvider = null;
    while (true)
    {
      return localNodeInformationProvider;
      localNodeInformationProvider = (NodeInformationProvider)this.nodeInformationProviders.get(paramString);
    }
  }

  private void init()
  {
    instances.put(this.connection, this);
    this.connection.addConnectionListener(new ConnectionListener(this)
    {
      public void connectionClosed()
      {
        ServiceDiscoveryManager.access$2().remove(ServiceDiscoveryManager.access$0(this.this$0));
      }

      public void connectionClosedOnError()
      {
      }

      public void reconnectingIn()
      {
      }

      public void reconnectionFailed()
      {
      }

      public void reconnectionSuccessful()
      {
      }
    });
    PacketTypeFilter localPacketTypeFilter1 = new PacketTypeFilter(Presence.class);
    3 local3 = new PacketInterceptor(this)
    {
      public void interceptPacket()
      {
        if (ServiceDiscoveryManager.access$3(this.this$0) != null)
        {
          String str = ServiceDiscoveryManager.access$4(this.this$0);
          paramPacket.addExtension(new CapsExtension(ServiceDiscoveryManager.access$3(this.this$0).getNode(), str, "sha-1"));
        }
      }
    };
    this.connection.addPacketInterceptor(local3, localPacketTypeFilter1);
    PacketTypeFilter localPacketTypeFilter2 = new PacketTypeFilter(DiscoverItems.class);
    4 local4 = new PacketListener(this)
    {
      public void processPacket()
      {
        DiscoverItems localDiscoverItems2;
        Iterator localIterator;
        DiscoverItems localDiscoverItems1 = (DiscoverItems)paramPacket;
        if ((localDiscoverItems1 != null) && (localDiscoverItems1.getType() == IQ.Type.GET))
        {
          localDiscoverItems2 = new DiscoverItems();
          localDiscoverItems2.setType(IQ.Type.RESULT);
          localDiscoverItems2.setTo(localDiscoverItems1.getFrom());
          localDiscoverItems2.setPacketID(localDiscoverItems1.getPacketID());
          localDiscoverItems2.setNode(localDiscoverItems1.getNode());
          NodeInformationProvider localNodeInformationProvider = ServiceDiscoveryManager.access$5(this.this$0, localDiscoverItems1.getNode());
          if (localNodeInformationProvider == null)
            break label138;
          List localList = localNodeInformationProvider.getNodeItems();
          if (localList != null)
          {
            localIterator = localList.iterator();
            if (localIterator.hasNext())
              break label121;
          }
        }
        while (true)
        {
          label138: 
          do
            while (true)
            {
              ServiceDiscoveryManager.access$0(this.this$0).sendPacket(localDiscoverItems2);
              return;
              label121: localDiscoverItems2.addItem((DiscoverItems.Item)localIterator.next());
            }
          while (localDiscoverItems1.getNode() == null);
          localDiscoverItems2.setType(IQ.Type.ERROR);
          localDiscoverItems2.setError(new XMPPError(XMPPError.Condition.item_not_found));
        }
      }
    };
    this.connection.addPacketListener(local4, localPacketTypeFilter2);
    PacketTypeFilter localPacketTypeFilter3 = new PacketTypeFilter(DiscoverInfo.class);
    5 local5 = new PacketListener(this)
    {
      public void processPacket()
      {
        DiscoverInfo localDiscoverInfo2;
        DiscoverInfo localDiscoverInfo1 = (DiscoverInfo)paramPacket;
        if ((localDiscoverInfo1 != null) && (localDiscoverInfo1.getType() == IQ.Type.GET))
        {
          localDiscoverInfo2 = new DiscoverInfo();
          localDiscoverInfo2.setType(IQ.Type.RESULT);
          localDiscoverInfo2.setTo(localDiscoverInfo1.getFrom());
          localDiscoverInfo2.setPacketID(localDiscoverInfo1.getPacketID());
          localDiscoverInfo2.setNode(localDiscoverInfo1.getNode());
          if ((localDiscoverInfo1.getNode() != null) && (ServiceDiscoveryManager.access$3(this.this$0) != null))
            break label95;
          this.this$0.addDiscoverInfoTo(localDiscoverInfo2);
        }
        while (true)
        {
          do
          {
            ServiceDiscoveryManager.access$0(this.this$0).sendPacket(localDiscoverInfo2);
            label95: return;
          }
          while (ServiceDiscoveryManager.access$3(this.this$0).getNode() + "#" + ServiceDiscoveryManager.access$4(this.this$0).equals(localDiscoverInfo1.getNode()));
          NodeInformationProvider localNodeInformationProvider = ServiceDiscoveryManager.access$5(this.this$0, localDiscoverInfo1.getNode());
          if (localNodeInformationProvider != null)
          {
            Iterator localIterator2;
            List localList1 = localNodeInformationProvider.getNodeFeatures();
            if (localList1 != null)
              localIterator2 = localList1.iterator();
            while (true)
            {
              List localList2;
              do
              {
                if (localIterator2.hasNext())
                  break label244;
                localList2 = localNodeInformationProvider.getNodeIdentities();
              }
              while (localList2 == null);
              Iterator localIterator1 = localList2.iterator();
              while (true)
              {
                if (!(localIterator1.hasNext()));
                localDiscoverInfo2.addIdentity((DiscoverInfo.Identity)localIterator1.next());
              }
              label244: localDiscoverInfo2.addFeature((String)localIterator2.next());
            }
          }
          localDiscoverInfo2.setType(IQ.Type.ERROR);
          localDiscoverInfo2.setError(new XMPPError(XMPPError.Condition.item_not_found));
        }
      }
    };
    this.connection.addPacketListener(local5, localPacketTypeFilter3);
  }

  public static boolean isNonCapsCachingEnabled()
  {
    return cacheNonCaps;
  }

  private boolean isSendPresence()
  {
    return this.sendPresence;
  }

  private void renewEntityCapsVersion()
  {
    if ((this.connection instanceof XMPPConnection) && (this.capsManager != null))
      this.capsManager.calculateEntityCapsVersion(getOwnDiscoverInfo(), identityType, identityName, this.features, this.extendedInfo);
  }

  public static void setIdentityName(String paramString)
  {
    identityName = paramString;
  }

  public static void setIdentityType(String paramString)
  {
    identityType = paramString;
  }

  public static void setNonCapsCaching(boolean paramBoolean)
  {
    cacheNonCaps = true;
  }

  private void setSendPresence()
  {
    this.sendPresence = true;
  }

  // ERROR //
  public void addDiscoverInfoTo(DiscoverInfo paramDiscoverInfo)
  {
    // Byte code:
    //   0: new 218	org/jivesoftware/smackx/packet/DiscoverInfo$Identity
    //   3: dup
    //   4: ldc 220
    //   6: invokestatic 222	org/jivesoftware/smackx/ServiceDiscoveryManager:getIdentityName	()Ljava/lang/String;
    //   9: invokespecial 225	org/jivesoftware/smackx/packet/DiscoverInfo$Identity:<init>	(Ljava/lang/String;Ljava/lang/String;)V
    //   12: astore_2
    //   13: aload_2
    //   14: invokestatic 227	org/jivesoftware/smackx/ServiceDiscoveryManager:getIdentityType	()Ljava/lang/String;
    //   17: invokevirtual 230	org/jivesoftware/smackx/packet/DiscoverInfo$Identity:setType	(Ljava/lang/String;)V
    //   20: aload_1
    //   21: aload_2
    //   22: invokevirtual 234	org/jivesoftware/smackx/packet/DiscoverInfo:addIdentity	(Lorg/jivesoftware/smackx/packet/DiscoverInfo$Identity;)V
    //   25: aload_0
    //   26: getfield 84	org/jivesoftware/smackx/ServiceDiscoveryManager:features	Ljava/util/List;
    //   29: astore_3
    //   30: aload_3
    //   31: monitorenter
    //   32: aload_1
    //   33: ldc 236
    //   35: invokevirtual 239	org/jivesoftware/smackx/packet/DiscoverInfo:addFeature	(Ljava/lang/String;)V
    //   38: aload_0
    //   39: invokevirtual 243	org/jivesoftware/smackx/ServiceDiscoveryManager:getFeatures	()Ljava/util/Iterator;
    //   42: astore 5
    //   44: aload 5
    //   46: invokeinterface 248 1 0
    //   51: ifne +21 -> 72
    //   54: aload_0
    //   55: getfield 86	org/jivesoftware/smackx/ServiceDiscoveryManager:extendedInfo	Lorg/jivesoftware/smackx/packet/DataForm;
    //   58: ifnull +11 -> 69
    //   61: aload_1
    //   62: aload_0
    //   63: getfield 86	org/jivesoftware/smackx/ServiceDiscoveryManager:extendedInfo	Lorg/jivesoftware/smackx/packet/DataForm;
    //   66: invokevirtual 252	org/jivesoftware/smackx/packet/DiscoverInfo:addExtension	(Lorg/jivesoftware/smack/packet/PacketExtension;)V
    //   69: aload_3
    //   70: monitorexit
    //   71: return
    //   72: aload_1
    //   73: aload 5
    //   75: invokeinterface 256 1 0
    //   80: checkcast 258	java/lang/String
    //   83: invokevirtual 239	org/jivesoftware/smackx/packet/DiscoverInfo:addFeature	(Ljava/lang/String;)V
    //   86: goto -42 -> 44
    //   89: astore 4
    //   91: aload_3
    //   92: monitorexit
    //   93: aload 4
    //   95: athrow
    //
    // Exception table:
    //   from	to	target	type
    //   32	93	89	finally
  }

  public void addFeature(String paramString)
  {
    synchronized (this.features)
    {
      this.features.add(paramString);
      renewEntityCapsVersion();
      return;
    }
  }

  public boolean canPublishItems(String paramString)
    throws XMPPException
  {
    return canPublishItems(discoverInfo(paramString));
  }

  public DiscoverInfo discoverInfo(String paramString)
    throws XMPPException
  {
    String str;
    Object localObject;
    DiscoverInfo localDiscoverInfo1 = discoverInfoByCaps(paramString);
    if (localDiscoverInfo1 != null)
      localObject = localDiscoverInfo1;
    while (true)
    {
      return localObject;
      str = null;
      if (this.capsManager != null)
        str = this.capsManager.getNodeVersionByUser(paramString);
      if ((!(cacheNonCaps)) || (str != null) || (!(this.nonCapsCache.containsKey(paramString))))
        break;
      localObject = (DiscoverInfo)this.nonCapsCache.get(paramString);
    }
    DiscoverInfo localDiscoverInfo2 = discoverInfo(paramString, str);
    if ((str != null) && (this.capsManager != null))
      EntityCapsManager.addDiscoverInfoByNode(str, localDiscoverInfo2);
    while (true)
    {
      do
        while (true)
          localObject = localDiscoverInfo2;
      while ((!(cacheNonCaps)) || (str != null));
      this.nonCapsCache.put(paramString, localDiscoverInfo2);
    }
  }

  public DiscoverInfo discoverInfo(String paramString1, String paramString2)
    throws XMPPException
  {
    DiscoverInfo localDiscoverInfo = new DiscoverInfo();
    localDiscoverInfo.setType(IQ.Type.GET);
    localDiscoverInfo.setTo(paramString1);
    localDiscoverInfo.setNode(paramString2);
    PacketCollector localPacketCollector = this.connection.createPacketCollector(new PacketIDFilter(localDiscoverInfo.getPacketID()));
    this.connection.sendPacket(localDiscoverInfo);
    IQ localIQ = (IQ)localPacketCollector.nextResult(SmackConfiguration.getPacketReplyTimeout());
    localPacketCollector.cancel();
    if (localIQ == null)
      throw new XMPPException("No response from the server.");
    if (localIQ.getType() == IQ.Type.ERROR)
      throw new XMPPException(localIQ.getError());
    return ((DiscoverInfo)localIQ);
  }

  public DiscoverInfo discoverInfoByCaps(String paramString)
    throws XMPPException
  {
    DiscoverInfo localDiscoverInfo2;
    DiscoverInfo localDiscoverInfo1 = this.capsManager.getDiscoverInfoByUser(paramString);
    if (localDiscoverInfo1 != null)
    {
      DiscoverInfo localDiscoverInfo3 = cloneDiscoverInfo(localDiscoverInfo1);
      localDiscoverInfo3.setFrom(paramString);
      localDiscoverInfo2 = localDiscoverInfo3;
    }
    while (true)
    {
      return localDiscoverInfo2;
      localDiscoverInfo2 = null;
    }
  }

  public DiscoverItems discoverItems(String paramString)
    throws XMPPException
  {
    return discoverItems(paramString, null);
  }

  public DiscoverItems discoverItems(String paramString1, String paramString2)
    throws XMPPException
  {
    DiscoverItems localDiscoverItems = new DiscoverItems();
    localDiscoverItems.setType(IQ.Type.GET);
    localDiscoverItems.setTo(paramString1);
    localDiscoverItems.setNode(paramString2);
    PacketCollector localPacketCollector = this.connection.createPacketCollector(new PacketIDFilter(localDiscoverItems.getPacketID()));
    this.connection.sendPacket(localDiscoverItems);
    IQ localIQ = (IQ)localPacketCollector.nextResult(SmackConfiguration.getPacketReplyTimeout());
    localPacketCollector.cancel();
    if (localIQ == null)
      throw new XMPPException("No response from the server.");
    if (localIQ.getType() == IQ.Type.ERROR)
      throw new XMPPException(localIQ.getError());
    return ((DiscoverItems)localIQ);
  }

  public EntityCapsManager getEntityCapsManager()
  {
    return this.capsManager;
  }

  public Iterator<String> getFeatures()
  {
    synchronized (this.features)
    {
      Iterator localIterator = Collections.unmodifiableList(new ArrayList(this.features)).iterator();
      return localIterator;
    }
  }

  public DiscoverInfo getOwnDiscoverInfo()
  {
    DiscoverInfo localDiscoverInfo = new DiscoverInfo();
    localDiscoverInfo.setType(IQ.Type.RESULT);
    localDiscoverInfo.setNode(this.capsManager.getNode() + "#" + getEntityCapsVersion());
    addDiscoverInfoTo(localDiscoverInfo);
    return localDiscoverInfo;
  }

  public boolean includesFeature(String paramString)
  {
    synchronized (this.features)
    {
      boolean bool = this.features.contains(paramString);
      return bool;
    }
  }

  public void publishItems(String paramString1, String paramString2, DiscoverItems paramDiscoverItems)
    throws XMPPException
  {
    paramDiscoverItems.setType(IQ.Type.SET);
    paramDiscoverItems.setTo(paramString1);
    paramDiscoverItems.setNode(paramString2);
    PacketCollector localPacketCollector = this.connection.createPacketCollector(new PacketIDFilter(paramDiscoverItems.getPacketID()));
    this.connection.sendPacket(paramDiscoverItems);
    IQ localIQ = (IQ)localPacketCollector.nextResult(SmackConfiguration.getPacketReplyTimeout());
    localPacketCollector.cancel();
    if (localIQ == null)
      throw new XMPPException("No response from the server.");
    if (localIQ.getType() == IQ.Type.ERROR)
      throw new XMPPException(localIQ.getError());
  }

  public void publishItems(String paramString, DiscoverItems paramDiscoverItems)
    throws XMPPException
  {
    publishItems(paramString, null, paramDiscoverItems);
  }

  public void removeExtendedInfo()
  {
    this.extendedInfo = null;
    renewEntityCapsVersion();
  }

  public void removeFeature(String paramString)
  {
    synchronized (this.features)
    {
      this.features.remove(paramString);
      renewEntityCapsVersion();
      return;
    }
  }

  public void removeNodeInformationProvider(String paramString)
  {
    this.nodeInformationProviders.remove(paramString);
  }

  public void setEntityCapsManager(EntityCapsManager paramEntityCapsManager)
  {
    this.capsManager = paramEntityCapsManager;
    if ((this.connection.getCapsNode() != null) && (this.connection.getHost() != null))
      this.capsManager.addUserCapsNode(this.connection.getHost(), this.connection.getCapsNode());
    this.capsManager.addPacketListener(this.connection);
  }

  public void setExtendedInfo(DataForm paramDataForm)
  {
    this.extendedInfo = paramDataForm;
    renewEntityCapsVersion();
  }

  public void setNodeInformationProvider(String paramString, NodeInformationProvider paramNodeInformationProvider)
  {
    this.nodeInformationProviders.put(paramString, paramNodeInformationProvider);
  }

  private class CapsPresenceRenewer
  implements CapsVerListener
  {
    public void capsVerUpdated()
    {
      if ((((XMPPConnection)ServiceDiscoveryManager.access$0(this.this$0)).isAuthenticated()) && (((((XMPPConnection)ServiceDiscoveryManager.access$0(this.this$0)).isSendPresence()) || (ServiceDiscoveryManager.access$1(this.this$0)))))
      {
        Presence localPresence = new Presence(Presence.Type.available);
        ServiceDiscoveryManager.access$0(this.this$0).sendPacket(localPresence);
      }
    }
  }
}